#!/usr/bin/python
#Copyright (c) 2007-2008 Travis Fickett (tfickett at ufl dot edu)
#
#Permission is hereby granted, free of charge, to any person
#obtaining a copy of this software and associated documentation
#files (the "Software"), to deal in the Software without
#restriction, including without limitation the rights to use,
#copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the
#Software is furnished to do so, subject to the following
#conditions:
#
#The above copyright notice and this permission notice shall be
#included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
#OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
#NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
#HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
#WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
#OTHER DEALINGS IN THE SOFTWARE.

#Tk NMEA sentance interpetor and graphical application.
#This code is based off of the reverse engineered NMEA documentation
#that was included with gpsdrive.  For (what should be) obvious reasons
#I am not responsible for your death if you crash into a rock using this
#software.
# please see the file LICENSE for licensing information
#software plays havok with IDLE !!!! don't even try to run it from IDLE

#http://gpsd.berlios.de/NMEA.txt
#Also see the Maretron USB100 Manual, Under Appendix A NMEA 2000 to 0183 Translations
#http://maretron.com/support/manuals.php
#The manual is copyright Maretron, so its probably a bad idea to source from it.

from Tkinter import *                  #Tkinter
from pyNMEA import pyNMEAparser
import tkMessageBox
import threading
#import serial                   #serial port library
import re
import os

root = Tk()
psr = pyNMEAparser()

class PollSerial (threading.Thread):      #serial port polling thread
	#tempwin = Tk()
	SERIAL_PORT = "COM1"            		# default shit
	SERIAL_BAUD = "4800"
	SERIAL_LOGENABLE = False        		#log data?
	SERIAL_LOGFILE = "seriallog.txt"		#where to log it too
	
	SERIAL_TIME = StringVar()       		#utc time
	SERIAL_HEADING = StringVar()    		#will hold heading
	SERIAL_SPEED = StringVar()      		#speed
	SERIAL_LAT = StringVar()        		#lat
	SERIAL_LON = StringVar()        		#lon
	SERIAL_FIX = StringVar()        		#fix status string
	SERIAL_DEPTH = StringVar()
	
	keepgoing = 1
	def setPort(self, PORT, BAUD):
		'''setup port infos, pass strings please'''
		self.SERIAL_PORT = PORT             # remember to always use self so we don't get new variables (stupid people forget this all the time)
		self.SERIAL_BAUD = BAUD
	def enableLog(self, filename):
		#self.SERIAL_LOGENABLE = True
		self.SERIAL_LOGFILE = filename
		self.SERIAL_LOG = open(self.SERIAL_LOGFILE, "a")
	def murderPort():
		#not really in use
		self.keepgoing = 0
		#print "Serial Port has been murdered"
	def run(self):
		#print "Thread Started"
		SERIAL_TEMP = ""                #holds serial data before split
		SERIAL_SPLIT = ""               # list of sentance fields
		self.SERIAL_TIME.set(psr.TIME.text)
		self.SERIAL_SPEED.set(psr.SOG.text)
		self.SERIAL_HEADING.set(psr.COG.text)
		self.SERIAL_LAT.set(psr.LAT.text)
		self.SERIAL_LON.set(psr.LON.text)
		self.SERIAL_FIX.set(psr.FIX.text)
		self.SERIAL_DEPTH.set(psr.DBT.text)					# this might be working need to test w// real transducer
		try:
			SERIAL_HW = serial.Serial(port=self.SERIAL_PORT,baudrate=self.SERIAL_BAUD,timeout=1)
		except serial.SerialException:
			tkMessageBox.showerror("Serial Port Error", "Sorry Failed to open serial port: "+str(SERIAL_PORT))# this doesnnt have a self. so it causes an exception ### this is deliberate
			exit(1)
		while self.keepgoing == 1:
			try:                				#try to read a line from the serial port
				#print "Ready waiting for line"
				SERIAL_TEMP = SERIAL_HW.readline()
			except serial.SerialException:  	#if it fails quit because the program was shutdown (probably)
				if self.SERIAL_LOG == True:
					self.SERIAL_LOG.close()
				return
			else:               				#if it worked update parser and display vars
				#print "Fooz"
				#print SERIAL_TEMP
				psr.parseSentance(SERIAL_TEMP)
				self.SERIAL_TIME.set(psr.TIME.text)
				self.SERIAL_SPEED.set(psr.SOG.text)
				self.SERIAL_HEADING.set(psr.COG.text)
				self.SERIAL_LAT.set(psr.LAT.text)
				self.SERIAL_LON.set(psr.LON.text)
				self.SERIAL_FIX.set(psr.FIX.text)
				self.SERIAL_DEPTH.set(psr.DBT.text)
		SERIAL_HW.close()
		self.SERIAL_LOG.close()
		print "O gnoes I AR DED"


serialcontroller = PollSerial()
serialcontroller.setPort("COM9","4800")
serialcontroller.enableLog("log.txt")
serialcontroller.start()

#This needs to be some sort of factory
def openSOG():
	SOGwin = Toplevel()             # For future refrence this must be a toplevel
	SOGwinlabel = Label(SOGwin,textvariable=serialcontroller.SERIAL_SPEED,font=("Helvetica",25)).pack()
	SOGwin.title("SOG")
	SOGwin.mainloop()

def openCOG():
	COGwin= Toplevel()
	COGwinlabel = Label(COGwin,textvariable=serialcontroller.SERIAL_HEADING, font=("Helvetica",25)).pack()
	COGwin.title("COG")
	COGwin.mainloop()

def openTime():
	Timewin= Toplevel()
	Timewinlabel = Label(Timewin,textvariable=serialcontroller.SERIAL_TIME, font=("Helvetica",25)).pack()
	Timewin.title("Time")
	Timewin.mainloop()
def openLatLon():
	LATwin= Toplevel()
	LATwinlabel = Label(LATwin,textvariable=serialcontroller.SERIAL_LAT, font=("Helvetica",25)).pack()
	LONwinlabel = Label(LATwin, textvariable=serialcontroller.SERIAL_LON, font=("Helvetica",25)).pack()
	LATwin.title("Latittude/Longitude")
	LATwin.mainloop()
def openFixStatus():
	FIXwin= Toplevel()
	FIXwinlabel = Label(FIXwin,textvariable=serialcontroller.SERIAL_FIX, font=("Helvetica",25)).pack()
	FIXwin.title("Fix Status")
	FIXwin.mainloop()
def openDepth():
	DBTwin= Toplevel()
	DBTwinlabel = Label(DBTwin,textvariable=serialcontroller.SERIAL_DEPTH, font=("Helvetica",25)).pack()
	DBTwin.title("DBT")
	DBTwin.mainloop()
def openChartWindow():						# one day this thing will show charts
	chartwin = Toplevel()
	w = Canvas(chartwin, width=512, height=512)
	#w.create_image(image=PhotoImage(file="chart.ppm"))
	w.pack()
	chartwin.mainloop()
def optionsMenu():
	options = Toplevel()
	
	options.title("Configure pyNavigate")
	options.mainloop()
def LogData():
	if serialcontroller.SERIAL_LOGENABLE == False:
		serialcontroller.SERIAL_LOG.write("Now Logging Data\n")
		serialcontroller.SERIAL_LOGENABLE = True
	else:
		serialcontroller.SERIAL_LOGENABLE = False
		serialcontroller.SERIAL_LOG.write("Not logging data anymore\n")
	
sogdisp = Label(root,textvariable=serialcontroller.SERIAL_SPEED,font=("Helvetica",25)).pack()   #add a label watching a variable
cogdisp = Label(root,textvariable=serialcontroller.SERIAL_HEADING,font=("Helvetica",25)).pack()
timedisp = Label(root,textvariable=serialcontroller.SERIAL_TIME,font=("Helvetica",25)).pack()
LATdisp = Label(root,textvariable=serialcontroller.SERIAL_LAT,font=("Helvetica",25)).pack()
LONdisp = Label(root,textvariable=serialcontroller.SERIAL_LON,font=("Helvetica",25)).pack()
FIXdisp = Label(root,textvariable=serialcontroller.SERIAL_FIX,font=("Helvetica",25)).pack()
DBTdisp = Label(root,textvariable=serialcontroller.SERIAL_DEPTH,font=("Helvetica",25)).pack()

rootmenu = Menu(root)
filemenu = Menu(rootmenu, tearoff=0)

newmenu = Menu(filemenu, tearoff=0)

newmenu.add_command(label="SOG",command=openSOG)
newmenu.add_command(label="COG",command=openCOG)
newmenu.add_command(label="Time",command=openTime)
newmenu.add_command(label="Position",command=openLatLon)
#newmenu.add_command(label="Longitude",command=openCOG)
newmenu.add_command(label="Fix Status",command=openFixStatus)
newmenu.add_command(label="Depth",command=openDepth)

filemenu.add_cascade(label="New Display",menu=newmenu)
filemenu.add_command(label="ChartWindow",command=openChartWindow)
filemenu.add_command(label="Options",command=optionsMenu)
filemenu.add_checkbutton(label="Log to File", command=LogData)
#filemenu.add_separator()
#filemenu.add_command(label="Exit",command=root.quit)

rootmenu.add_cascade(label="File", menu=filemenu)

root.config(menu=rootmenu)
root.title("pyNavigate")
#options.title("GPS OPTIONS")

root.mainloop()
serialcontroller.keepgoing = 0              # ugly nasty hack to shutdown serial port

